package jwt

import (
	"errors"
	"github.com/dgrijalva/jwt-go"
	"time"
)

var (
	BORROWER  uint8 = 1
	MANAGER   uint8 = 2
	WORKER    uint8 = 3
	SUPERUSER uint8 = 4
)

// TokenExpireDuration Expiration time 7 days
const TokenExpireDuration = time.Hour * 24 * 7

// Set the signature key
var mySercet = []byte("bms")

type Claim struct {
	Bo BorrowerClaims
	Ma ManagerClaims
	Wo WorkerClaims
	Sp SuperClaims
}
type SuperClaims struct {
	SuperUserID uint `json:"super_user_id"`
	jwt.StandardClaims
}

type BorrowerClaims struct {
	UserID uint `json:"super_user_id"`
	jwt.StandardClaims
}

type ManagerClaims struct {
	ManagerID uint `json:"manager_id"`
	jwt.StandardClaims
}

type WorkerClaims struct {
	WorkerID uint `json:"worker_id"`
	jwt.StandardClaims
}

// GenToken Build Web JWT
// typ 看上面的 vars
func GenToken(ID uint, typ uint8) (string, error) {
	// Create our own statement
	var c Claim
	switch typ {
	case BORROWER:
		{
			c.Bo = BorrowerClaims{
				UserID: ID,
				StandardClaims: jwt.StandardClaims{
					ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 过期时间
					Issuer:    "spm-b2-borrower",                          // 签发人
				},
			}
		}
	case MANAGER:
		{
			c.Ma = ManagerClaims{
				ManagerID: ID,
				StandardClaims: jwt.StandardClaims{
					ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 过期时间
					Issuer:    "spm-b2-manager",                           // 签发人
				},
			}

		}
	case WORKER:
		{
			c.Wo = WorkerClaims{
				WorkerID: ID,
				StandardClaims: jwt.StandardClaims{
					ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 过期时间
					Issuer:    "spm-b2-worker",                            // 签发人
				},
			}
		}
	case SUPERUSER:
		{
			c.Sp = SuperClaims{
				SuperUserID: ID,
				StandardClaims: jwt.StandardClaims{
					ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 过期时间
					Issuer:    "spm-b2-superuser",                         // 签发人
				},
			}
		}
	}
	// Create a signature object using the SigningMethodHS256 signature method
	var token *jwt.Token
	switch typ {
	case BORROWER:
		token = jwt.NewWithClaims(jwt.SigningMethodHS256, c.Bo)
	case MANAGER:
		token = jwt.NewWithClaims(jwt.SigningMethodHS256, c.Ma)
	case WORKER:
		token = jwt.NewWithClaims(jwt.SigningMethodHS256, c.Wo)
	case SUPERUSER:
		token = jwt.NewWithClaims(jwt.SigningMethodHS256, c.Sp)
	}
	// Use the specified seek signature and get the fully encoded token
	return token.SignedString(mySercet)
}

func ParseTokenBorrower(tokenString string) (*BorrowerClaims, error) {
	// parse token
	var mc = new(BorrowerClaims)
	token, err := jwt.ParseWithClaims(tokenString, mc, func(token *jwt.Token) (i interface{}, err error) {
		return mySercet, nil
	})
	if err != nil {
		return nil, err
	}
	if token.Valid {
		return mc, nil
	}
	return nil, errors.New("invalid token")
}
func ParseTokenSuperuser(tokenString string) (*SuperClaims, error) {
	// parse token
	var mc = new(SuperClaims)
	token, err := jwt.ParseWithClaims(tokenString, mc, func(token *jwt.Token) (i interface{}, err error) {
		return mySercet, nil
	})
	if err != nil {
		return nil, err
	}
	if token.Valid {
		return mc, nil
	}
	return nil, errors.New("invalid token")
}

func ParseTokenManager(tokenString string) (*ManagerClaims, error) {
	// parse token
	var mc = new(ManagerClaims)
	token, err := jwt.ParseWithClaims(tokenString, mc, func(token *jwt.Token) (i interface{}, err error) {
		return mySercet, nil
	})
	if err != nil {
		return nil, err
	}
	if token.Valid {
		return mc, nil
	}
	return nil, errors.New("invalid token")
}

func ParseTokenWorker(tokenString string) (*WorkerClaims, error) {
	// parse token
	var mc = new(WorkerClaims)
	token, err := jwt.ParseWithClaims(tokenString, mc, func(token *jwt.Token) (i interface{}, err error) {
		return mySercet, nil
	})
	if err != nil {
		return nil, err
	}
	if token.Valid {
		return mc, nil
	}
	return nil, errors.New("invalid token")
}
